import time

import numpy as np
import pandas as pd

# 构造测试数据
df = pd.DataFrame(
    {"name": ["金陵新九村 2 室 1 厅 52.59 平米",
              "场门口小区 14 号 1 室 1 厅 27.75 平米",
              "锦江花苑 2 室 1 厅 72.25 平米",
              "世茂滨江新城 2 室 2 厅 127.07 平米",
              "汉北街 8 号 2 室 1 厅 52.37 平米",
              "凤凰西街 223 号 2 室 1 厅 80.37 平米",
              "西桥 3 室 1 厅 75.85 平米",
              "聚福园一期 2 室 1 厅 79.6 平米",
              "港口小区 2 室 1 厅 75.73 平米",
              "新河二村 1 室 1 厅 38.76 平米"],
     "houseInfo": ["南 北 其他",
                   "南 其他",
                   "南 其他",
                   "西北 精装",
                   "南 北 简装",
                   "南 北 其他",
                   "南 简装",
                   "南 北 精装",
                   "南 简装",
                   "西 简装"],
     "dealDate": ["2023.03.18",
                  "2023.03.18",
                  "2023.03.18",
                  "2023.03.18",
                  "2023.03.18",
                  "2023.03.18",
                  "2023.03.18",
                  "2023.03.18",
                  "2023.03.18",
                  "2023.03.18"],
     "totalPrice": [122.8,
                    261.6,
                    478,
                    407,
                    174,
                    260,
                    234.5,
                    545,
                    188,
                    314.2],
     "positionInfo": ["中楼层(共 7 层) 板楼",
                      "低楼层(共 6 层) 板楼",
                      "低楼层(共 12 层) 塔楼",
                      "低楼层(共 53 层) 板塔结合",
                      "中楼层(共 4 层) 板楼",
                      "中楼层(共 8 层) 板楼",
                      "高楼层(共 4 层) 板楼",
                      "低楼层(共 6 层) 板楼",
                      "低楼层(共 7 层) 板楼",
                      "高楼层(共 7 层) 板楼"],
     "unitPrice": [23351,
                   94271,
                   66160,
                   32030,
                   33226,
                   32351,
                   30917,
                   68468,
                   24826,
                   81063],
     "advantage": ["房屋满五年/近地铁",
                   "房屋满五年/近地铁",
                   "nan",
                   "房屋满五年",
                   "近地铁",
                   "房屋满两年/近地铁",
                   "房屋满五年/近地铁",
                   "房屋满五年/近地铁",
                   "房屋满五年",
                   "房屋满两年"],
     "listPrice": ["挂牌 128 万",
                   "挂牌 280 万",
                   "挂牌 510 万",
                   "挂牌 418 万",
                   "挂牌 186 万",
                   "挂牌 276 万",
                   "挂牌 248 万",
                   "挂牌 555 万",
                   "挂牌 200 万",
                   "挂牌 320 万"],
     "dealCycleDays": ["成交周期 3 天",
                       "成交周期 13 天",
                       "成交周期 70 天",
                       "成交周期 614 天",
                       "成交周期 273 天",
                       "成交周期 127 天",
                       "成交周期 1012 天",
                       "成交周期 538 天",
                       "成交周期 218 天",
                       "成交周期 151 天"]})

# 将测试数据扩大至千万级
for _ in range(20):
    df = pd.concat([df, df], axis=0, ignore_index=True)


# 构造装饰器函数测试每种方法的耗时
def test_time(func_main):
    def wrapper(*args, **kwargs):
        start = time.time()
        func_main(*args, **kwargs)
        print(f"{func_main.__name__}耗时{time.time() - start}")
        return func_main

    return wrapper


# 第一种处理方式 常用的apply写法
@test_time
def deal_1():
    def filter_data(row):
        if 300 > row["totalPrice"] > 200:
            return "OK"

        if row["unitPrice"] < 10000:
            return "OK"

        return "NG"

    df["评估"] = df.apply(filter_data, axis=1)


# 第二种通过np.where来完成同样的操作
@test_time
def deal_2():
    # 根据单价过滤
    cond_unit_price = np.where(
        df["unitPrice"] < 10000,
        "OK",
        "NG",
    )

    # 先根据总价过滤，不满足条件再用单价过滤
    cond_total_price = np.where(
        (df["totalPrice"] > 200) & (df["totalPrice"] < 300),
        "OK",
        cond_unit_price,
    )

    df["评估"] = cond_total_price


@test_time
def deal_3():
    # 设置 “优，良，中” 的判断条件
    conditions = [
        df["houseInfo"].str.contains("精装")
        & df["positionInfo"].str.contains("中楼层")
        & df["advantage"].str.contains("近地铁"),

        (df["totalPrice"] < 300) & df["advantage"].str.contains("近地铁"),

        df["totalPrice"] < 400,
    ]
    choices = ["优", "良", "中"]

    # 默认为 “差”
    df["评估"] = np.select(conditions, choices, default="差")


if __name__ == '__main__':
    deal_1()
    # 这里删除了第一次处理后的评估列
    df.drop('评估', axis=1, inplace=True)
    deal_2()
    df.drop('评估', axis=1, inplace=True)
    # 当前测试
    # deal_1耗时89.00527024269104
    # deal_2耗时0.6512570381164551
    # 通过测试在处理大量数据时np.where耗时大大减少
    deal_3()
